package es.udc.acs.consorcio.client;


import java.net.SocketTimeoutException;
import java.util.logging.Level;

import es.udc.acs.consorcio.sesion.Sesion;
import es.udc.acs.parser.ParserMensaje;
import es.udc.acs.udp.ClienteUDP;
import es.udc.acs.utils.CodigosFAP;
import es.udc.acs.utils.FormateadorDatos;
import es.udc.acs.utils.GestorProperties;

public class DataClient {
	
	private DataClient(){}
	
	public static String sendMessage(String message,Sesion sesion){
		
		int canal;
		
		GestorProperties.tratarMensaje(
				"DataClient:mensaje enviado: ",message);
		
		FormateadorDatos.formatearMensaje(message,true);
		
		String response = CodigosFAP.CR_CONSULTA_DENEGADA;
		try {
			response = ClienteUDP.sendMessage(
					sesion.getHost(),sesion.getPort(), message, 60);
			
		} catch (SocketTimeoutException e) {
			
			if (sesion.obtenerEstado().equals("Recibiendo"))  {
			
				if(!ControlClient.startRecuperacion(sesion)){
					return CodigosFAP.CR_CONSULTA_DENEGADA;
				}
				
				sesion.enRecuperacion();
				
				canal = Integer.parseInt(ParserMensaje.obtenerCanal(
							ParserMensaje.obtenerSubcabecera(message)));
				//Pedir la respuesta de ese canal
				response = sesion.getResponseCanal(canal);
				
				if(!ControlClient.finRecuperacion(sesion)){
					GestorProperties.getConsorcioLog().getLogger().
							log(Level.ALL, "<" + sesion.getBanco() 
									+ "> No se pudo salir de recuperacion ");
				}else {
					sesion.mostrarCanales();
					sesion.finRecuperacion();
				}
			}
		}
		
		return tramitaRespuesta(response, sesion);
	}
	
	private static String tramitaRespuesta(String response, Sesion sesion){
		String tipo;
		String subcabecera;
		String codResp;
		String respSesion;
		
		FormateadorDatos.formatearMensaje(response,true);

		GestorProperties.tratarMensaje(
				"DataClient:mensaje recibido: ",response);
		
		String origen  = ParserMensaje.obtenerOrigen(response);
		String destino = ParserMensaje.obtenerDestino(response);

		// comprobacion del destino y origen
		if (!destino.equals(
					GestorProperties.devolverPropiedad(GestorProperties.IDCONSORCIO)) 
				|| !origen.equals(sesion.getBanco())) {
			System.out.println("DataClient:origen y destino erroneos");
			return null;
		}
		
		tipo = ParserMensaje.obtenerTipo(response);
		
		// puede pasar que este equivocado o que de un error el banco que
		// no se contempla en el FAP
		if (!CodigosFAP.esRespuestaDatos(tipo)){
			return null;
		}
		
		subcabecera = ParserMensaje.obtenerSubcabecera(response);
		codResp 	= ParserMensaje.obtenerCodRes(response);
		
		if(CodigosFAP.esRespuestaValida(codResp)){
			respSesion = sesion.receiveMessage(
					ParserMensaje.obtenerCanal(subcabecera), 
					ParserMensaje.obtenerNumMensaje(subcabecera));
			if(respSesion.equals(CodigosFAP.CE_CORRECTO)){
				
				// si no se acepta no hay cuerpo
				if (codResp.equals(CodigosFAP.CR_CONSULTA_ACEPTADA)) {
					return codResp 
							+ ParserMensaje.obtenerCuerpoSubCRes(response);
				} else {
					return codResp;
				}
			} 
		}
		return null;
	}
}
